#ifndef __CALIB_
#define __CALIB_

#include <opencv2/opencv.hpp>

#include <cctype>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <iostream>
#include <memory>

using namespace cv;
using namespace std;

enum
{
    DETECTION = 0,
    CAPTURING = 1,
    CALIBRATED = 2
};
enum Pattern
{
    CHESSBOARD,
    CIRCLES_GRID,
    ASYMMETRIC_CIRCLES_GRID
};

double computeReprojectionErrors(
    const vector<vector<Point3f>> &,
    const vector<vector<Point2f>> &,
    const vector<Mat> &, const vector<Mat> &,
    const Mat &, const Mat &,
    vector<float> &);

void calcChessboardCorners(Size, float, vector<Point3f> &, Pattern patternType);

bool runCalibration(vector<vector<Point2f>> imagePoints,
                    Size imageSize, Size boardSize, Pattern patternType,
                    float squareSize, float aspectRatio,
                    float grid_width, bool release_object,
                    int flags, Mat &cameraMatrix, Mat &distCoeffs,
                    vector<Mat> &rvecs, vector<Mat> &tvecs,
                    vector<float> &reprojErrs,
                    vector<Point3f> &newObjPoints,
                    double &totalAvgErr);

void saveCameraParams(const string &filename,
                      Size imageSize, Size boardSize,
                      float squareSize, float aspectRatio, int flags,
                      const Mat &cameraMatrix, const Mat &distCoeffs,
                      const vector<Mat> &rvecs, const vector<Mat> &tvecs,
                      const vector<float> &reprojErrs,
                      const vector<vector<Point2f>> &imagePoints,
                      const vector<Point3f> &newObjPoints,
                      double totalAvgErr);
bool readStringList(const string &filename, vector<string> &l);

bool runAndSave(const string &outputFilename,
                const vector<vector<Point2f>> &imagePoints,
                Size imageSize, Size boardSize, Pattern patternType, float squareSize,
                float grid_width, bool release_object,
                float aspectRatio, int flags, Mat &cameraMatrix,
                Mat &distCoeffs, bool writeExtrinsics, bool writePoints, bool writeGrid);
#endif